using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;

namespace KaroContentPipeline
{
    /// <summary>
    /// This class will be instantiated by the XNA Framework Content Pipeline
    /// to apply custom processing to content data, converting an object of
    /// type TInput to TOutput. The input and output types may be the same if
    /// the processor wishes to alter data without changing its type.
    ///
    /// This should be part of a Content Pipeline Extension Library project.
    ///
    /// TODO: change the ContentProcessor attribute to specify the correct
    /// display name for this processor.
    /// </summary>
    [ContentProcessor(DisplayName = "KaroContentPipeline.BoundingBoxProcessor")]
    public class BoundingBoxProcessor : ModelProcessor
    {
        public override ModelContent Process(NodeContent input, ContentProcessorContext context)
        {
            Vector3 minPoint = Vector3.Zero;
            Vector3 maxPoint = Vector3.Zero;

            foreach (NodeContent node in input.Children)
            {
                MeshContent mesh = node as MeshContent;

                if (mesh != null)
                {
                    foreach (GeometryContent geometry in mesh.Geometry)
                    {
                        // looking for the min and max points
                        foreach (int index in geometry.Indices)
                        {
                            Vector3 vertex = geometry.Vertices.Positions[index];

                            if (vertex.X < minPoint.X) minPoint.X = vertex.X;
                            if (vertex.Y < minPoint.Y) minPoint.Y = vertex.Y;
                            if (vertex.Z < minPoint.Z) minPoint.Z = vertex.Z;

                            if (vertex.X > maxPoint.X) maxPoint.X = vertex.X;
                            if (vertex.Y > maxPoint.Y) maxPoint.Y = vertex.Y;
                            if (vertex.Z > maxPoint.Z) maxPoint.Z = vertex.Z;
                        }
                    }
                }
            }

            // processing model using default processor
            ModelContent content = base.Process(input, context);

            // adding the bound box as a tag of the mesh
            content.Meshes[0].Tag = new BoundingBox(minPoint, maxPoint);

            return content;
        }
    }
}